﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aribaccio;
using Aribaccio.Device;
using BDPAutodetect.Device;

namespace BDPAutodetect.Hardware
{
    /// <summary>
    /// 设备管理
    /// </summary>
    public class DeviceManager
    {
        /// <summary>
        /// 设备列表集合
        /// </summary>
        public List<IDevice<IDevicePara>> Devices { get; private set; }
        /// <summary>
        /// 设备集合数量
        /// </summary>
        public int Count { get { return this.Devices != null ? this.Devices.Count : 0; } }

        /// <summary>
        /// 构造函数
        /// </summary>
        public DeviceManager()
        {
            this.Devices = new List<IDevice<IDevicePara>>();
        }

        /// <summary>
        /// 判断设备是否存在
        /// </summary>
        /// <param name="argDeviceName">设备名称</param>
        /// <returns></returns>
        public bool IsExist(string argDeviceName)
        {
            if (this.Devices == null) return false;
            return this.Devices.Exists(D => D.DevicePara.DeviceName == argDeviceName);
        }

        /// <summary>
        /// 判断设备是否存在
        /// </summary>
        /// <param name="argDevice">设备对象</param>
        /// <returns></returns>
        public bool IsExist(IDevice<IDevicePara> argDevice)
        {
            if (Devices == null || argDevice == null) return false;
            return Devices.Exists(D => D.DevicePara.DeviceName == argDevice.DevicePara.DeviceName);
        }

        /// <summary>
        /// 判断设备是否都处于关闭状态
        /// </summary>
        /// <param name="argDeviceName">设备名称 </param>
        /// <returns></returns>
        public bool IsExistClosed(string argDeviceName)
        {
            if (this.Devices == null || string.IsNullOrWhiteSpace(argDeviceName)) return false;
            IDevice<IDevicePara>? Device = GetDataDevice(argDeviceName);
            if (Device == null) return false;
            return IsExistClosed(Device);
        }

        /// <summary>
        /// 判断设备是否都处于关闭状态
        /// </summary>
        /// <param name="argDevice">设备对象</param>
        /// <returns></returns>
        public bool IsExistClosed(IDevice<IDevicePara> argDevice)
        {
            if (this.Devices == null || argDevice == null) return false;
            return argDevice.IsOpen ? false : true;
        }

        /// <summary>
        /// 判断所有设备是否都处于关闭状态
        /// </summary>
        /// <returns></returns>
        public bool IsExistClosed()
        {
            if (this.Devices == null)  return true; 
            return !this.Devices.Exists(D => D.IsOpen == true);
        }


        /// <summary>
        /// 新增设备
        /// </summary>
        /// <param name="argDevice">设备对象</param>
        public void InsertDevice(IDevice<IDevicePara> argDevice)
        {
            if (argDevice == null) return;
            if (this.Devices == null) { this.Devices = new List<IDevice<IDevicePara>>(); }
            if (!IsExist(argDevice))
            {
                this.Devices.Add(argDevice);
            }
        }

        /// <summary>
        /// 删除设备
        /// </summary>
        /// <param name="argDeviceName">设备名称</param>
        public void DeleteDevice(string argDeviceName)
        {
            if (this.Devices == null || string.IsNullOrWhiteSpace(argDeviceName)) return;
            IDevice<IDevicePara>? Device = GetDataDevice(argDeviceName);
            if (Device != null)
            {
                DeleteDevice(Device);
            }
        }

        /// <summary>
        /// 删除设备
        /// </summary>
        /// <param name="argDevice">设备对象</param>
        public void DeleteDevice(IDevice<IDevicePara> argDevice)
        {
            if (this.Devices == null || argDevice == null) return;
            if (argDevice.IsOpen) { argDevice.Close(); }
            this.Devices.Remove(argDevice);
        }

        /// <summary>
        /// 打开单个设备
        /// </summary>
        /// <param name="argDeviceName">设备名称</param>
        /// <returns></returns>
        public bool OpenDevice(string argDeviceName)
        {
            if (this.Devices == null || string.IsNullOrWhiteSpace(argDeviceName)) return false;
            IDevice<IDevicePara>? Device = GetDataDevice(argDeviceName);
            if (Device == null) return false;
            return OpenDevice(Device);
        }

        /// <summary>
        /// 打开单个设备
        /// </summary>
        /// <param name="argDevice">设备对象</param>
        /// <returns></returns>
        public bool OpenDevice(IDevice<IDevicePara> argDevice)
        {
            if (this.Devices == null || argDevice == null)  return false; 
            if (argDevice.IsOpen) return true;
            return argDevice.Open().ResultState;
        }

        /// <summary>
        /// 打开所有设备
        /// </summary>
        /// <returns></returns>
        public bool OpenDeviceAll()
        {
            bool boolResult = true;
            foreach (IDevice<IDevicePara> Device in this.Devices)
            {
                if (!Device.Open().ResultState) { boolResult = false; }
            }
            return boolResult;
        }

        /// <summary>
        /// 关闭单个设备
        /// </summary>
        /// <param name="argDeviceName">设备名称</param>
        public void CloseDevice(string argDeviceName)
        {
            if (this.Devices == null || string.IsNullOrWhiteSpace(argDeviceName))  return; 
            IDevice<IDevicePara>? Device = this.GetDataDevice(argDeviceName);
            if (Device != null)
            {
                this.CloseDevice(Device);
            }
        }

        /// <summary>
        /// 关闭单个设备
        /// </summary>
        /// <param name="argDevice">设备对象</param>
        public void CloseDevice(IDevice<IDevicePara> argDevice)
        {
            if (this.Devices == null || argDevice == null) return; 
            if (argDevice.IsOpen)
            {
                argDevice.Close();
            }
        }

        /// <summary>
        /// 关闭所有设备
        /// </summary>
        public void CloseDeviceAll()
        {
            foreach (IDevice<IDevicePara> Device in this.Devices)
            {
                if (!Device.IsOpen) continue;
                Device.Close();
            }
        }

        /// <summary>
        /// 清除所有设备列表
        /// </summary>
        public void ClearDeviceAll()
        {
            if (this.Devices == null)  return; 
            this.CloseDeviceAll();
            this.Devices.Clear();
        }


        /// <summary>
        /// 获取设备对象
        /// </summary>
        /// <param name="argIndex">设备索引</param>
        /// <returns></returns>
        public IDevice<IDevicePara>? GetDataDevice(int argIndex)
        {
            if (this.Devices == null) return null; 
            return (argIndex >= 0 && argIndex < this.Count) ? this.Devices[argIndex] : null;
        }

        /// <summary>
        /// 获取设备对象, 返回符合条件的第一个设备
        /// </summary>
        /// <param name="argDeviceName">设备名称</param>
        /// <returns></returns>
        public IDevice<IDevicePara>? GetDataDevice(string argDeviceName)
        {
            if (this.Devices == null || string.IsNullOrWhiteSpace(argDeviceName))  return null; 
            return this.Devices.Where(v => v.DevicePara.DeviceName == argDeviceName).FirstOrDefault();
        }

        /// <summary>
        /// 获取设备对象, 返回符合条件的第一个设备
        /// </summary>
        /// <param name="argDeviceType">设备类型名称</param>
        /// <returns></returns>
        public IDevice<IDevicePara>? GetDataDevice(DeviceType argDeviceType)
        {
            if (this.Devices == null) return null; 
            return this.Devices.Where(v => v.DevicePara.DeviceType == argDeviceType.ToStringName()).FirstOrDefault();
        }

        /// <summary>
        /// 获取设备对象,返回符合条件的第一个设备
        /// </summary>
        /// <param name="argDeviceType">设备类型</param>
        /// <param name="argModuleType">设备模组类型</param>
        /// <returns></returns>
        public IDevice<IDevicePara>? GetDataDevice(DeviceType argDeviceType, DeviceModule argModuleType)
        {
            if (this.Devices == null) return null; 
            return this.Devices.Where(v => v.DevicePara.DeviceType == argDeviceType.ToStringName() && v.DevicePara.ModuleType == argModuleType).FirstOrDefault();
        }

        /// <summary>
        /// 获取未使用设备对象,返回符合条件的第一个设备
        /// </summary>
        /// <param name="argDeviceType">设备类型</param>
        /// <returns></returns>
        public IDevice<IDevicePara>? GetDataDeviceNotUsed(DeviceType argDeviceType)
        {
            if (this.Devices == null) return null; 
            return this.Devices.Where(v => v.DevicePara.DeviceType == argDeviceType.ToStringName() && !v.IsUsed).FirstOrDefault();
        }

        /// <summary>
        /// 获取设备名称
        /// </summary>
        /// <param name="argDeviceCaption">设备描述</param>
        /// <returns>设备名称</returns>
        public string GetDeviceName(string argDeviceCaption)
        {
            if (this.Devices == null || string.IsNullOrWhiteSpace(argDeviceCaption)) return string.Empty; 
            IDevice<IDevicePara>? Device = this.Devices.Where(v => v.DevicePara.DeviceCaption == argDeviceCaption).FirstOrDefault();
            return Device != null ? Device.DevicePara.DeviceName : string.Empty;
        }

        /// <summary>
        /// 获取设备描述
        /// </summary>
        /// <param name="argDeviceName">设备名称</param>
        /// <returns></returns>
        public string GetDeviceCaption(string argDeviceName)
        {
            if (this.Devices == null || string.IsNullOrWhiteSpace(argDeviceName)) return string.Empty; 
            IDevice<IDevicePara>? Device = this.Devices.Where(v => v.DevicePara.DeviceName == argDeviceName).FirstOrDefault();
            return Device != null ? Device.DevicePara.DeviceCaption : string.Empty;
        }

        /// <summary>
        /// 获取设备类型
        /// </summary>
        /// <param name="argDeviceName">设备名称</param>
        /// <returns></returns>
        public DeviceType GetDeviceType(string argDeviceName)
        {
            if (this.Devices == null || string.IsNullOrWhiteSpace(argDeviceName)) return DeviceType.None; 
            IDevice<IDevicePara>? Device = this.Devices.Where(v => v.DevicePara.DeviceName == argDeviceName).FirstOrDefault();
            return Device != null ? Device.DevicePara.DeviceType.ToEnum<DeviceType>() : DeviceType.None;
        }

        /// <summary>
        /// 获取设备列表
        /// </summary>
        /// <param name="argDeviceType">设备类型</param>
        /// <returns></returns>
        public List<IDevice<IDevicePara>> GetDeviceList(DeviceType argDeviceType)
        {
            if (this.Devices == null || argDeviceType == DeviceType.None) return new List<IDevice<IDevicePara>>(); 
            return this.Devices.FindAll(v => v.DevicePara.DeviceType == argDeviceType.ToStringName());
        }

        /// <summary>
        /// 绑定数据设备
        /// </summary>
        /// <param name="argDeviceName">设备名称</param>
        /// <param name="argDeviceTransData">设备传输数据接口</param>
        /// <returns></returns>
        public IDevice<IDevicePara>? BindingDevice(string argDeviceName, IDeviceTrans<IDeviceData<IDevice<IDevicePara>>> argDeviceTransData)
        {
            IDevice<IDevicePara>? Device = this.GetDataDevice(argDeviceName);
            if (Device != null)
            {
                Device.BindingDevice(argDeviceTransData);
            }
            return Device;
        }
      
        /// <summary>
        /// 断开数据设备
        /// </summary>
        /// <param name="argDeviceName"></param>
        /// <param name="argDeviceTransData">设备传输数据接口</param>
        public void ClearBindingDevice(string argDeviceName, IDeviceTrans<IDeviceData<IDevice<IDevicePara>>> argDeviceTransData)
        {
            IDevice<IDevicePara>? Device = this.GetDataDevice(argDeviceName);
            if (Device != null)
            {
                Device.ClearBindingDevice(argDeviceTransData);
            }
        }
    }
}
